package cbbx_sm.decision_maker;

import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import cbbx_sm.probabilistic_model.Cluster;
import cbbx_sm.probabilistic_model.Prediction;

/**
 * Very simple decision maker: it decides to probe the cluster with
 * the highest probability to contain an entity in the future state.
 * 
 * @author Alessio Della Motta - University of California, Irvine
 *
 */
public class MostLikelyClusterDecisionMaker implements IDecisionMaker {
	private double threshold = 0.0;
	
	public MostLikelyClusterDecisionMaker(double threshold){
		this.threshold = threshold;
	}
	
	public MostLikelyClusterDecisionMaker(){
		this(0.0);
	}
	
	@Override
	public Decision makeDecision(Prediction currentPrediction) {
		HashMap<Cluster, Double> probs = currentPrediction.getClusterProbabilities();
		HashMap<String, Cluster> clustersToProbe = new HashMap<String, Cluster>();
		HashMap<String, Double> clustersToProbeProbs = new HashMap<String, Double>();
		
		for (Cluster cluster : probs.keySet()){
			String curCameraId = cluster.getCameraId();
			double curProb = probs.get(cluster);
			
			/*
			 * If the current cluster is the first cluster analyzed for a certain
			 * camera, then we insert it into the possible candidates; otherwise,
			 * if there's a cluster of the same camera as a candidate, we control
			 * if its probability is lower and, in that case, we substitute it
			 * with the current analyzed cluster.
			 */
			if (curProb >= threshold){
				if (clustersToProbe.containsKey(curCameraId)){
					if(curProb > clustersToProbeProbs.get(curCameraId)){
						clustersToProbe.put(curCameraId, cluster);
						clustersToProbeProbs.put(curCameraId, curProb);
					}
				}
				else {
					clustersToProbe.put(curCameraId, cluster);
					clustersToProbeProbs.put(curCameraId, curProb);
				}
			}
		}
		
		List<CameraConfiguration> confs = new Vector<CameraConfiguration>();
		
		for (Cluster cluster : clustersToProbe.values())
			confs.add(new CameraConfiguration(cluster.getCameraId(), cluster));
		
		Decision decision = new Decision(confs);
		
		return decision;
	}
	
	@Override
	public String toString(){
		return "" + this.getClass().getSimpleName() +"_"+threshold;
	}
}
